<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
	<meta http-equiv="content-type" content="text/html;charset=utf-8" />
	<title>AXL Tutorial: TranzAm</title>
	<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<!-- menu -->
	<div id="navmain">
	<ul>
		<li><a href="index.html">Overview</a></li>
		<li><a href="install.html">Installation</a></li>
		<li><a href="config.html">Configurator</a></li>
		<li><a href="animation.html">Animation</a></li>
		<li><a href="framework.html">Framework</a></li>
		<li><a href="tranzam.html">Tutorial</a></li>
	</ul>
	</div>
	<div id="navsub">
	<ul>
		<li><a href="tranzam.html">Start</a></li>
		<li><a href="tranzam_a1.html">Article 1</a></li>
		<li><a href="tranzam_a2.html">Article 2</a></li>
		<li><a href="tranzam_a3.html">Article 3</a></li>
		<li><a href="tranzam_a4.html">Article 4</a></li>
		<li><a href="tranzam_a5.html">Article 5</a></li>
		<li><a href="tranzam_a6.html">Article 6</a></li>
		<li><a href="tranzam_a7.html">Article 7</a></li>
		<li><a href="tranzam_a8.html">Article 8</a></li>
		<li><a href="tranzam_a9.html">Article 9</a></li>
		<li><a href="tranzam_a10.html">Article 10</a></li>
	</ul><span class="smallprint">This menu will stay fixed with a proper browser.</span>
	<p>
	 <a href="http://jigsaw.w3.org/css-validator/">
	  <img style="border:0;width:88px;height:31px"
		   src="http://jigsaw.w3.org/css-validator/images/vcss" 
		   alt="Valid CSS!" />
	 </a>
	</p>
	<p>
      <a href="http://validator.w3.org/check?uri=referer"><img
          src="http://www.w3.org/Icons/valid-xhtml10"
          alt="Valid XHTML 1.0!" height="31" width="88" /></a>
    </p>
<p><a href="http://www.bloggerheads.com/bbc/"><img src="http://www.bloggerheads.com/bbc/bbc.gif" width="90" height="45"  
alt="Click here to find out why." /></a></p>
<p><a href="http://retrospec.sgn.net" ><img src="retrospec.gif" width="150" alt="Fine games" /></a></p>
	</div>
<!-- menu -->

	<div id="main">
	<a name="files"></a>
<h1>Introduction</h1>
In the previous lesson we created our menu, added an animated graphic and used multiple timer functions. In this lesson we will 
be adding collision detection to the car so that we can bump into foreground items (e.g. trees, mountains) and removing the dual 
control method we talked about removing in a previous lesson, dynamically adding the cups to the tile map and adding an override
timer to show that we have won the game. This is the start of the game taking shape and actually doing something :)
<h1>Structure</h1>
If you are manually creating the project 
    make file then use the one from lesson 5 and add the file game_wingame.cpp
    <br />The following files will be changed in this lesson:
    <ul>
    <li>game_vars.cpp: a few minor updates to add number of lives</li>
    <li>game_transam.cpp/h: Updated to add the cups to the map</li>
    <li>game_game.cpp/h: Cup placement and collection, damage, lives and game over</li>
    <li>game_car.cpp : Control changed back to a single control method, death animation added, tile collision/interaction</li>
    <li>game_wingame.cpp : New file to handle winning the game</li>
    </ul>
	<a name="source1"></a>
<h1>Mappy</h1>
<img src="images/tranzam_tiles.jpg" alt="tile value" style="float: right; padding-left: 10px;" />
Every tile you create within Mappy can store a number of custom values. They are set by double clicking on the tiles within Mappy. 
The screenshot shows the dialog that contains each tile's custom values. Note, within Mappy, the tiles are referred to as Blocks. If you 
open the mappyal.h header file from the libraries directory, this is defined near the top and is a struct called BLKSTR. 
The seven text boxes (with zero's) are called user1 to user7 and represent numeric values, the three checkboxes labelled 'other' are called 
unused1, unused2, unused3, and the four checkboxes labelled 'collision' are called tr, tl, bl, br (corresponding to the four corners they are 
drawn within the dialog box). The checkboxes are bit field values. These values can be set and used for any reason.
<br />
In our game we will be using them as follows:
<ul>
<li>unused1: this tile is PETROL</li>
<li>unused2: this tile is a ROAD and we can increase the top speed</li>
<li>unused3: tile is a CUP (collect all 8 and win the game, yeah!)</li>
<li>tr: tile is rough terrain and affects the car</li>
<li>bl: collision with this tile causes instant death. No damage allowed</li>
<li>br: tile is blank (only these tiles can hold CUPs)</li>
<li>user5: tile states how much to slow down car by</li>
<li>user6: tile states the car will sustain damage if collision occurs</li>
</ul>
As you can see from the picture, this tile is a cactus, has the 'tl' item checked and is made up of a background tile
(sand) and a foreground tile (the cactus). In our code (explained in earlier lessons) that draws the tiles (game_game.cpp) the function MapDrawBGT(...)
will draw all the background items (the sand in this instance) and the function MapDrawFG(...) will draw the 
foreground tiles (the cactus in this instance).
<br />
If you are in the editor, double click on the first tile and use the two buttons to the right of the BG/FG pictures ('&lt;' and '&gt;') to 
navigate through the tiles and see what values are set.
</br />
Mappy provides a number of functions for retrieving block information. What we will be doing is finding out 
where the car is, getting the block details and checking the values. The function to retrieve block information 
has the signature: <span class="code">BLKSTR* CurrentBlock=MapGetBlockInPixels (this->mapx,this->mapy);</span>. This function 
will get the block at a pixel location, which is how we are storing the car details). BLKSTR as mentioned returns a
block structure containing the values of the tile. In the code walkthrough for the Car we will discuss this further.

<h1>Code Walkthrough (game_game.cpp)</h1>
When a new game/level starts we will randomly place the cups on the map (the point of the game is to collection all the cups).
 This is done in the LoadLevel() function.<br />
The code relevant to us is the loop at the bottom of the function. <span class="code">MapGetBlock(x,y)</span> is a Mappy
function that gets a block (stored in a struct called BLKSTR, as mentioned above) using tile locations. 
We are using the value 'br' to signify that it is a block that is empty and can be used to hold a cup. In our map 
'br' is stored for the blank ground tile (the yellowish coloured tile). Once our randomly searched tile is of this type
we use the Mappy function <span class="code">MapSetBlock(x,y,n)</span>, where x/y are the locations we found using MapGetBlock, 
and n is the tile number (in the picture above for the cactus, you can see that it is 42.). We then hold the locations of the cups in an array.
<br />
What we've also done in the code is an option to reload completely a map during InitialiseLevel(), using the 'Reload' parameter. This is so that 
we only load and setup the map on first entry (from the menu).
<br />Within the TransAmGameDrawing function we are showing (as debug data) on screen the locations of the cups, so 
when we test the game we can find them. We are also updating the display to show the number of lives left and cups collected.
<br />We've also added (to TransAmGameLogic) an update to handle dying. Within the Car class a data member 'State' is added to show 
the car's status (NORMAL, DYING, DEAD). This is explained in the next section.

<h1>Branching Timers</h1>
Within your timer logic (and drawing, but usually logic) you might want to perform an extended or complex task. For example, a game pause/options menu. 
But we don't want to make it a completely separate timer event (as in one of our four GAME_GAME, GAME_LOGO, GAME_MENU, GAME_EXIT) as it is linked in some way
to the current timer event. You may want to do this, for no reason other than to avoid lots of conditional checks in the logic.
<br />
We are doing this in the game when you've won the game, as ultimately we want a fancy ending :)
<br />In the game_game.cpp timer Function TransAmGameLogic we have the following code at the start:
<div class="code">
if(NumCups==MaxNumCups)
{
	newLevelRequired=true;
	clear_keybuf();
	if(!WinGame)
		GameFramework->SetAutoGameLoopOverride(WinGameLogic,WinGameDrawing);
	else
	{
		NumCups=0;
		GameFramework->ChangeTimerType(GAME_MENU);
	}

	WinGame=true;
	return false;
}
</div>
Firstly the code is only entered when we have all the cups. Secondly, when the game is over we call the 
ChangeTimerType to the menu so that on exit we go back to the menu. This is the same call as we use when 
the ESCape key is pressed.
<br />
As mentioned earlier, calling SetAutoGameLoopOverride will tell the Framework to start calling the two 
functions passed in at it's next pass, rather the ones it has currently (in this case GAME_GAME). The key difference is that
on exiting the function, control returns back to the suspended loop (in our case GAME_GAME).
<br />So, ignoring what WinGameLogic/WinGameDrawing does, once our game over routine has finished, 
control will be returned to TransAmGameLogic. At this point we still have all the cups but the flag WinGame has been set
to true, so the end game is not called again and instead the GAME_MENU is set.
<h1>game_wingame.cpp/h</h1>
This file contains the logic/drawing functions we set in the timer override function in the previous section. 
It will eventually hold a glorious game over screen. For now, all it does within the WinGameLogic is wait for the ENTER 
key to be pressed, and in the WinGameDrawing it outputs a message.
<br />
What has happened is within the TransAmGameTimer function we told the Framework that it should stop calling 
TransAmGameLogic/Drawing within it's FPS based timer, and instead call WinGameLogic/Drawing functions.
This is all it does. When we press ENTER, it returns true, which signifies to the Framework that our 
override function has finished and it should return to calling the functions it has. In effect, we are simply 
changing the drawing/logic. This is really good as the overhead is minimal (i.e. two pointer changes) but 
we can compartmentalise all our games functionality and know that it is within a FPS based timer loop.
<h1>Collision Detection</h1>
In our Car class we know what location on the map we are, so in order to perform collision detection and process each tile, we
use the MapGetBlock(...) function to get the block details of the tile the car is currently on.
Obviously because the car can move in pixel increments and our tiles are quite large (32x32), we could end up spanning 
multiple tiles. In this version what we are going to do is presume that the car is moving at a reasonable speed 
at all times and only check the centre point of the car (full pixel perfect collision is probably not necessary, though 
at some point in the future, a polygon based tile detection may be a good idea).
<h1>game_car.cpp/h</h1>
In the Car header file we add a function 'CheckCollision' that we will call every frame to check for collisions and we add the variables we have already discussed, e.g. State, Damage. We are also going to 
add a turbo option. This will simply increase the top speed if the player is on a road.
<br />
At the end of the NextMove method (our main method that is called every frame from within our TransAmGameLogic function) we 
call this new method (CheckCollision).
<br />
The top of this method gives a summary of what the block values do. Because our car is placed in pixels, 
we call the <span class="code">MapGetBlockInPixels</span> Mappy function that returns a block using pixels rather than 
tile locations. From this block we will then check each of the custom variables of the tile/block to see if it is set, then perform the 
relevant actions:
<ul>
<li>br : this is a blank tile so we can just exit to save us some time</li>
<li>bl : this is a flag that says the player is dead (currently, only the mountain tile is this). We will explain the code in this section later</li>
<li>unused3: We have found a cup. We update the cup count and then remove the cup by using the SetBlock Mappy function to place a blank tile</li>
<li>unused2: This is a road, so we set a flag to say that we have a higher top speed</li>
<li>user6 : This is a block that we can collide with and take damage (e.g. tree, cactus). We reduce the damage (when it reaches zero, a life is lost) and set the temperature to fully on. We also bounce the car by revering the angle. This results in the car reversing direction and slowing down. It slows down because in a previous lesson we disabled acceleration when the temperature was high. The code relating to CAR_DYING will be explained next</li>
<li>tr : this simply slows down the car, e.g. the water, grass or mud tiles. The SpeedFactor variable is applied to the acceleration/velocity function. In effect this is a percentage of the top speed.</li>
</ul>
I'm hoping at this point, you've followed the code and saw that it is pretty simple to get/set/use tile values and apply them within a game.
<h1>Animations, Fading, Countdown Timers</h1>
<h2>Animations</h2>
Hopefully you know that when you create an animation, the constructor is passed an ID so that we know what graphic/animation to use from the animations.xml file.
For example, 
<div class="code">
DisplayTemperature	=new Animation(GameLibrary,"temperature");
Cup			=new Animation(GameLibrary,"cup");
</div>
The Animation class has a method, SetNewAnimation, that lets us change the animation of the animation object.
What this does, is changes it's internal data to point to the new graphics and it's values.
For example, if you have a player and you have different animations for walking left and right you could do something like:
<div class="code">
if(key[KEY_LEFT]) Player->SetNewAnimation("walk_left");
if(key[KEY_RIGHT]) Player->SetNewAnimation("walk_right");
</div>
And on pressing the key, the animation would change.<br />
In our animations.xml file we have the following entry:
<div class="code">
&lt;animation  id="dying"		
	bmp_file="transam.bmp"
	millisecondwait="300"
	sheetitemwidth="32" sheetitemheight="32"
	originx="99" originy="0"
	sequencecount="2" 
/&gt;
</div>
Which describes an animation of two frames called 'dying' and corresponds to the following two images in our 
sheet graphics file transam.bmp<br />
<img src="images/tranzam_dying.jpg" alt="dying" />
<br />It will repeat itself every 300 milliseconds.<br />
Going back to the game, what we want to do on dying is change the car to this dying animation. Within 
the game_car.cpp, checkcollision() method, you'll see in the statements that check the 'br' and 'user6' flags, we determine if the player is to die. 
If so, we change the animation: <span class="code">car->SetNewAnimation("dying");</span>
When the level or game restarts, the Player object is deleted and recreated, thus returning back to normal.
<br />
The only thing left to explain is why we have CAR_DYING and CAR_DEAD, and what 'car->SetCustomCountDown' does.
<br />
Addressing the first point, when the player is dead, as well as changing to the dying 
animation, we wish to show the animation for a fixed time before continuing with the game. If we didn't, we would 
never see the dying animation. For this reason we have two flags. The first CAR_DYING tells the code that
the player is dying (i.e. it will continue to draw the game and update logic, but it will not do any more collision detection). The 
second flag, CAR_DEAD will be set after a number of seconds after CAR_DYING to tell the game that we are actually dead. This then lets 
the TransAmGameLogic know that we need to reduce the life count and start the level again (or end it if no more lives are left).
How it knows a number of seconds are passed is done via the Animation object...
<h2>Countdown Timers</h2>
As you know, the game runs in a timer context and is how animations work. This is done because each animation's NextMove() method is called 
every frame. So, as a no cost extra to the timer there is a method available for each Animation called 'SetCustomCountDown'.
This takes in two parameters, an id number and a value in milliseconds. The id is there because we allow a maximum of five 
(which seemed a nice compromise between speed and size when writing the Animation class). This can easily be changed, 
indeed it is a #define at the top of the axl.h file for you to change to optimise the system.
<br />
Once this function is called, the Animation object updates it's countdown timers every frame. 
To find out when a countdown timer has finished we need to check whether the timer has reached zero.
Rather than code another method to retrieve the value, probably due to laziness, you access the timer value 
via the array ReadOnly_Timers. It holds a value of 1 if that timer has expired.
<br />
Within our game_game.cpp file we check this as follows:
<div class="code">
if(Player->State==CAR_DYING &amp;&amp; Player->car->ReadOnly_Timers[1])
</div>
This says that if the timer 1 has been set (i.e. it is down to zero) and the car's state is dying then the 
we know the player is dead. In this case (it is within TransAmGameLogic) we reduce the life count and either start the level again or 
quit if game over.
<br />
Hopefully, you will see that using custom timers is very useful. btw, 'car' is the Player object's animation.
<br />
<h2>Fading</h2>
Although not used in this game so far, each animation object can be faded. The functionality is similar to the way the custom 
timers are used. To fade an animation you call the FadeIn or FadeOut methods. These either fade from the 
current bitmap to a colour or fade in from a colour to the current bitmap. Examples can be found in the AXL documentation 
for the Animation (from the menu to the left). 
<br />The method does not support alpha-channels, hence why you have to specify a colour. <strong>However</strong> 
this is not a problem. One of the parameters you pass in, 'alterbmp', is a true/false flag and tells the animation object
whether to actually perform the fade (i.e. alter the bitmap) or just pretend to do it. This sounds odd, but is useful 
in the case of the alpha-fade: The fade value of each Animation object is reflected in the ReadOnly_Timers array (that is 
used for the custom countdown) element zero, i.e. ReadOnly_Timers[0]. However, instead of simply showing a flag of when it is set, 
it contains the actual fade value in the range 0 to 255. This value is updated each frame and goes from 0 to 255, 255 to 0 in the 
time you specify. This then lets you use the Animation object to control the fade speed accurately for you, 
and you simply use this array element in your own code for fading, blending or whatever else you need this value for.

<h1>Allegro</h1>
Just to recap, we've seen how to change animations, how to add countdown timers, how to suspend the current timer code and use another piece of code, 
how to store and read tile values to perform collision detection and other triggers within the game.<br />
So, all that remains is to compile the code and try out the game.
<h1>Next</h1>
In the next lesson, we will be updating the final two areas of our car's panel, the national and local radar maps.
<br /></div>
</body>
</html>
